

from datetime import datetime
import os
import shutil
from PySide6.QtCore import Qt, QThread, Signal, Slot, QDateTime, QTimer, QObject
import requests

from gui.schemas.enumeration import UserRole
from gui.utils.redis_client import RedisConnector,LocalDataManager


class DataSyncWorker(QThread):
    """数据同步工作线程"""
    
    sync_progress = Signal(int)
    sync_complete = Signal(bool, str)
    file_synced = Signal(str, str)  # 文件ID, 状态
    
    def __init__(self, redis_connector, local_manager):
        super().__init__()
        # self.username = username
        self.redis:RedisConnector = redis_connector
        self.local:LocalDataManager = local_manager
        self.tabs_to_sync = []
        self.username = ""
        self.role = "普通用户"
        self.stop_requested = False
    
    def set_tabs_to_sync(self, tabs):
        """设置要同步的tab列表"""
        self.tabs_to_sync = tabs
    
    def run(self):
        """执行数据同步"""
        try:
            total_files = 0
            synced_files = 0
            
            for tab in self.tabs_to_sync:
                tab_name = tab.tab_data.get("name")
                redis_files = self.redis.get_tab_files(tab_name,) if self.redis.is_connected() else []
                local_files = self.local.get_tab_files(tab_name)
                total_files += len(redis_files) + len(local_files)
            self.sync_progress.emit(0)
            
            for tab in self.tabs_to_sync:
                tab_name = tab.tab_data.get("name")
                if self.stop_requested:
                    self.sync_complete.emit(False, "同步被用户取消")
                    return
                
                # 同步Redis到本地
                if self.redis.is_connected(): # 可能涉及下载
                    redis_files = self.redis.get_tab_files(tab_name,)
                    redis_tab = self.redis.get_tab(tab_name,)
                    self.local.save_local_tab(tab_name, redis_tab)
                    for filename in redis_files:
                        if self.stop_requested:
                            self.sync_complete.emit(False, "同步被用户取消")
                            return
                        redis_data = self.redis.get_file_data(filename)
                        local_data = self.local.get_file_data(tab_name, filename)
                        redis_time = self._parse_time(redis_data.get("updatetime"))
                        local_time = self._parse_time(local_data.get("updatetime") if local_data else None)
                        is_pull = False # 角色权限检测
                        """
                        如果是标注人员就只能回去已经分配属于自己的文件
                        如果是检查员就只能回去已经分配属于自己的文件
                        """
                        if UserRole.ANNOTATOR in self.role:
                            owner = redis_data.get("file_attributes",{}).get("owner","")
                            if owner != "" and owner == self.username:
                                is_pull = True
                        elif UserRole.EMEND in self.role: # 检查员
                            is_pull = True
                        elif UserRole.ADMIN in self.role: # 管理员不能拉取同步数据
                            is_pull = False
                                
                        if not local_data or (redis_time and local_time and redis_time > local_time):
                            if redis_data and is_pull:
                                self.local.save_file_data(tab_name, filename, redis_data)
                                self.file_synced.emit(filename, "从Redis同步到本地")
                        if is_pull:
                            tab_dir = os.path.join( self.local.root_dir, tab_name)
                            file_url = redis_data.get("file_attributes",{}).get("file_url")
                            local_path = os.path.join(tab_dir, filename)
                            if not os.path.exists(local_path): # 如果不存在，则下载
                                try:
                                    if file_url.startswith("http"): # 可以是https
                                        # file_url = f"{file_path}/{filename}"
                                        r = requests.get(file_url)
                                        with open(local_path, "wb") as f:
                                            f.write(r.content)
                                    else:
                                        # file_url = os.path.join(base_url, filename)
                                        shutil.copy(file_url, local_path)
                                except Exception as e:
                                    print(f"获取 {file_url} 文件失败: {e}")
                        synced_files += 1
                        progress = int((synced_files / total_files) * 100) if total_files > 0 else 100
                        self.sync_progress.emit(progress)
                
                # 同步本地到Redis
                if self.redis.is_connected():
                    local_files = self.local.get_tab_files(tab_name)
                    local_tab = self.local.get_tab_file(tab_name)
                    if UserRole.ANNOTATOR in self.role:
                        self.redis.save_tab_data(tab_name, local_tab) # 只有管理员上传
                    for filename in local_files:
                        if self.stop_requested:
                            self.sync_complete.emit(False, "同步被用户取消")
                            return
                        
                        local_data = self.local.get_file_data(tab_name, filename)
                        redis_data = self.redis.get_file_data(filename)
                        redis_time = self._parse_time(redis_data.get("updatetime") if redis_data else None)
                        local_time = self._parse_time(local_data.get("updatetime"))
                        is_upload = False
                        if UserRole.ANNOTATOR in self.role:
                            owner = redis_data.get("file_attributes",{}).get("owner","")
                            if owner != "" and owner == self.username:
                                is_upload = True
                        elif UserRole.EMEND in self.role: # 检查员
                            is_upload = True
                        elif UserRole.ADMIN in self.role: # 管理员不能拉取同步数据
                            is_upload = False
                            
                        if local_data and (not redis_data or local_time and redis_time and local_time > redis_time) and is_upload:
                            if self.redis.save_file_data(filename, local_data):
                                self.redis.add_file_to_tab(tab_name, filename)
                                self.file_synced.emit(filename, "从本地同步到Redis")
                        
                        synced_files += 1
                        progress = int((synced_files / total_files) * 100) if total_files > 0 else 100
                        self.sync_progress.emit(progress)
            
            self.sync_complete.emit(True, f"成功同步 {synced_files} 个文件")
        except Exception as e:
            self.sync_complete.emit(False, f"同步过程中出错: {str(e)}")
    
    def stop_sync(self):
        """停止同步过程"""
        self.stop_requested = True
    
    def _parse_time(self, time_str):
        """解析时间字符串为datetime对象"""
        if not time_str:
            return None
        try:
            if '+' in time_str or 'Z' in time_str:
                return datetime.fromisoformat(time_str.replace('Z', '+00:00'))
            else:
                return datetime.fromisoformat(time_str)
        except:
            return None



